#include "udp.h"
#include <string>
//#include "uavdata.h"
ServerUDP::ServerUDP()
{
    // Initialize
}
ServerUDP::ServerUDP(int port, char * address)
{
    serv_port = port;
    serv_ip_address = address;
    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0)
    {
        perror("socket");
        //exit(1);
    }

    //允许多个套接字使用同一端口
    u_int yes;
    if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
    {
        perror("Reusing ADDR failed");
    }

    //将套接字和IP、端口绑定
    memset(&addr_serv, 0, sizeof(struct sockaddr_in));//每个字节用0填充
    addr_serv.sin_family = AF_INET;//使用IPV4地址
    addr_serv.sin_port = htons(serv_port);//端口
    //INADDR_ANY表示不管从哪个网卡接收，只要目的端口是SERV_PORT，就会被该应用程序接收。
    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  // Automatically acquire IP address
    len = sizeof(addr_serv);
    //绑定socket
    if (bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
    {
        perror("bind error");
//        exit(1);
    }
}


ServerUDP::ServerUDP(int port, char * address, bool multi)
{
    serv_port = port;
    serv_ip_address = address;
    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0)
    {
        perror("socket");
        //exit(1);
    }

    //允许多个套接字使用同一端口
    u_int yes;
    if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
    {
        perror("Reusing ADDR failed");
    }

    //将套接字和IP、端口绑定
    memset(&addr_serv, 0, sizeof(struct sockaddr_in));//每个字节用0填充
    addr_serv.sin_family = AF_INET;//使用IPV4地址
    addr_serv.sin_port = htons(serv_port);//端口
    //INADDR_ANY表示不管从哪个网卡接收，只要目的端口是SERV_PORT，就会被该应用程序接收。
    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  // Automatically acquire IP address
    len = sizeof(addr_serv);
    //绑定socket
    if (bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
    {
        perror("bind error");
//        exit(1);
    }

    if(multi)
    {
        struct ip_mreq mreq;
        mreq.imr_multiaddr.s_addr = inet_addr(serv_ip_address);
        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
        if(setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
        {
            perror("setsockopt");
        }
    }
}

void ServerUDP::setip_add(int port, char * address)
{
    serv_port = port;
    serv_ip_address = address;

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0)
    {
        perror("socket");
//        exit(1);
    }

    u_int yes;
    if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
    {
        perror("Reusing ADDR failed");
    }

    //将套接字和IP、端口绑定
    memset(&addr_serv, 0, sizeof(struct sockaddr_in));//每个字节用0填充
    addr_serv.sin_family = AF_INET;//使用IPV4地址
    addr_serv.sin_port = htons(serv_port);//端口
    //INADDR_ANY表示不管从哪个网卡接收，只要目的端口是SERV_PORT，就会被该应用程序接收。
    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  // Automatically acquire IP address
    len = sizeof(addr_serv);
    //绑定socket
    if (bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
    {
        perror("bind error");
//        exit(1);
    }
}


void ServerUDP::setip_add(int port, unsigned char * address)
{
    serv_port = port;
    un_serv_ip_address = address;

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0)
    {
        perror("socket");
//        exit(1);
    }

    u_int yes;
    if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
    {
        perror("Reusing ADDR failed");
    }

    //将套接字和IP、端口绑定
    memset(&addr_serv, 0, sizeof(struct sockaddr_in));//每个字节用0填充
    addr_serv.sin_family = AF_INET;//使用IPV4地址
    addr_serv.sin_port = htons(serv_port);//端口
    //INADDR_ANY表示不管从哪个网卡接收，只要目的端口是SERV_PORT，就会被该应用程序接收。
    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  // Automatically acquire IP address
    len = sizeof(addr_serv);
    //绑定socket
    if (bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
    {
        perror("bind error");
//        exit(1);
    }
}

int ServerUDP::receiveData(char * receive_buf, int num)
{
//    cout << "Service start: " << endl;
    recv_num = recvfrom(sock_fd, receive_buf, num, 0, (struct sockaddr*)&addr_serv, (socklen_t*)&len);
//    if (recv_num < 0)
//    {
//        perror("recvfrom error");
//        exit(1);
//    }
    return recv_num;
}

int ServerUDP::receiveData(unsigned char * receive_buf, int num)//阻塞接收
{
//    cout << "Service start: " << endl;
    recv_num = recvfrom(sock_fd, receive_buf, num, 0, (struct sockaddr*)&addr_serv, (socklen_t*)&len);
//    if (recv_num < 0)
//    {
//        perror("recvfrom error");
//        exit(1);
//    }
    return recv_num;
}

int ServerUDP::receiveData_nozs(char * receive_buf, int size)//非阻塞接收，若无数据立即返回 -1，不会阻塞线程
{
//    cout << "Service start: " << endl;
    recv_num = recvfrom(sock_fd, receive_buf, size, MSG_DONTWAIT, (struct sockaddr*)&addr_serv, (socklen_t*)&len);
//    if (recv_num < 0)
//    {
//        perror("recvfrom error");
//        exit(1);
//    }
    return recv_num;
}
int ServerUDP::receiveData_nozs(unsigned char *receive_buf, int size)
{
//    cout << "Service start: " << endl;
    recv_num = recvfrom(sock_fd, receive_buf, size, MSG_DONTWAIT, (struct sockaddr*)&addr_serv, (socklen_t*)&len);
//    if (recv_num < 0)
//    {
//        perror("recvfrom error");
//        exit(1);
//    }
    return recv_num;
}

int ServerUDP::sendData(char * send_buf, int size)
{
    send_num = sendto(sock_fd, send_buf, size, 0, (struct sockaddr *)&addr_serv, len);
    if (send_num < 0)
    {
        perror("sendto error");
//        exit(1);
    }
    return send_num;
}

int ServerUDP::sendData(unsigned char * send_buf, int size)
{
    send_num = sendto(sock_fd, send_buf, size, 0, (struct sockaddr *)&addr_serv, len);
    if (send_num < 0)
    {
        perror("sendto error");
//        exit(1);
    }
    return send_num;
}

void ServerUDP::printData(char * buf, int size)
{
    for (int i = 0; i < size; i++)
    {
        cout << hex << (uint)buf[i] << dec << " ";
    }
    cout << endl;
}

void ServerUDP::printData(unsigned char * buf, int size)
{
    for (int i = 0; i < size; i++)
    {
        cout << hex << (uint)buf[i] << dec << " ";
    }
    cout << endl;
}

ServerUDP::~ServerUDP()
{
    close(sock_fd);
}

ClientUDP::ClientUDP()
{

}

ClientUDP::ClientUDP(int port, char * address) {
    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0) {
        perror("socket");
    }
    dest_port = port;
    dest_ip_address = address;
    memset(&addr_client, 0, sizeof(addr_serv));
    addr_serv.sin_family = AF_INET;
    addr_serv.sin_addr.s_addr = inet_addr((char *)dest_ip_address);
    addr_serv.sin_port = htons(dest_port);//端口
    len = sizeof(addr_serv);
    len_client = sizeof(addr_client);
}


void ClientUDP::setip_add(int port, char * address)
{

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0)
    {
        perror("socket");
//        exit(1);
    }

    dest_port = port;
    dest_ip_address = address;
    //将套接字和IP、端口绑定
    memset(&addr_serv, 0, sizeof(addr_serv));//每个字节用0填充
    addr_serv.sin_family = AF_INET;//使用IPV4地址
    addr_serv.sin_port = htons(dest_port);//端口
    addr_serv.sin_addr.s_addr = inet_addr((char *)dest_ip_address);
    len = sizeof(addr_serv);
    len_client = sizeof(addr_client);
}

void ClientUDP::setip_add_multi(int port, char * address) {

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0) {
        perror("socket");
//        exit(1);
    }

    dest_port = port;
    dest_ip_address = address;
    unsigned char ttl = 1;
    if(setsockopt(sock_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl))<0)
    {
        perror("setsockopt");
    }
    //将套接字和IP、端口绑定
    memset(&addr_serv, 0, sizeof(addr_serv));//每个字节用0填充
    addr_serv.sin_family = AF_INET;//使用IPV4地址
    addr_serv.sin_port = htons(dest_port);//端口
    addr_serv.sin_addr.s_addr = inet_addr((char *) dest_ip_address);
    len = sizeof(addr_serv);
    len_client = sizeof(addr_client);
}


void ClientUDP::setip_add(int port, unsigned char * address)
{

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd < 0)
    {
        perror("socket");
//        exit(1);
    }

    dest_port = port;
    un_dest_ip_address = address;
    //将套接字和IP、端口绑定
    memset(&addr_serv, 0, sizeof(addr_serv));//每个字节用0填充
    addr_serv.sin_family = AF_INET;//使用IPV4地址
    addr_serv.sin_port = htons(dest_port);//端口
    addr_serv.sin_addr.s_addr = inet_addr((char *)dest_ip_address);
    len = sizeof(addr_serv);
    len_client = sizeof(addr_client);
}

int ClientUDP::receiveData(char * receive_buf, int size) {
    recv_num = recvfrom(sock_fd, receive_buf, size, 0, (struct sockaddr *) &addr_serv, (socklen_t * ) & len);
    if (recv_num < 0) {
        perror("recvfrom error");
    }
    return recv_num;
}

int ClientUDP::receiveData(unsigned char * receive_buf, int size) {
    recv_num = recvfrom(sock_fd, receive_buf, size, 0, (struct sockaddr *) &addr_serv, (socklen_t * ) & len);
    if (recv_num < 0) {
        perror("recvfrom error");
    }
    return recv_num;
}

int ClientUDP::receiveData_nozs(unsigned char * receive_buf, int size) {
    recv_num = recvfrom(sock_fd, receive_buf, size, MSG_DONTWAIT, (struct sockaddr *) &addr_serv, (socklen_t * ) & len);
    return recv_num;
}

int ClientUDP::receiveData_nozs(char * receive_buf, int size) {
    recv_num = recvfrom(sock_fd, receive_buf, size, MSG_DONTWAIT, (struct sockaddr *) &addr_serv, (socklen_t * ) & len);
    return recv_num;
}

int ClientUDP::sendData(char *send_buf, int size) {
    send_num = sendto(sock_fd, send_buf, size, 0, (struct sockaddr *)&addr_serv, len);
    if(send_num < 0)
    {
        perror("sendto error");
    }
    return send_num;
}

int ClientUDP::sendData(unsigned char *send_buf, int size) {
    send_num = sendto(sock_fd, send_buf, size, 0, (struct sockaddr *)&addr_serv, len);
    if(send_num < 0)
    {
        perror("sendto error");
    }
    return send_num;
}

void ClientUDP::printData(char *buf, int size) {
    for(int i = 0; i < size; i++){
        cout << hex << (uint)buf[i] <<dec << " ";
    }
    cout << endl << endl;
}

void ClientUDP::printData(unsigned char *buf, int size) {
    for(int i = 0; i < size; i++){
        cout << hex << (uint)buf[i] <<dec << " ";
    }
    cout << endl << endl;
}

ClientUDP::~ClientUDP()
{
    close(sock_fd);
}
